"""
Redis缓存管理器
"""
import json
import logging
import pickle
from typing import Any, Optional, Dict, List
import redis
from datetime import timedelta

from ..config.settings import CACHE_CONFIG

logger = logging.getLogger(__name__)

class CacheManager:
    """Redis缓存管理器"""
    
    def __init__(self):
        self.enable_cache = CACHE_CONFIG["enable_cache"]
        self.redis_client = None
        
        if self.enable_cache:
            self._init_redis_client()
    
    def _init_redis_client(self):
        """初始化Redis客户端"""
        try:
            self.redis_client = redis.Redis(
                host=CACHE_CONFIG["redis_host"],
                port=CACHE_CONFIG["redis_port"],
                password=CACHE_CONFIG["redis_password"],
                db=CACHE_CONFIG["redis_db"],
                decode_responses=False,  # 保持二进制模式以支持pickle
                socket_connect_timeout=5,
                socket_timeout=5
            )
            
            # 测试连接
            self.redis_client.ping()
            logger.info("Redis缓存连接成功")
            
        except Exception as e:
            logger.error(f"Redis缓存连接失败: {e}")
            self.redis_client = None
            self.enable_cache = False
    
    def _generate_key(self, prefix: str, *args) -> str:
        """生成缓存键"""
        key_parts = [prefix] + [str(arg) for arg in args]
        return ":".join(key_parts)
    
    def get(self, key: str, default: Any = None) -> Any:
        """
        获取缓存值
        
        Args:
            key: 缓存键
            default: 默认值
            
        Returns:
            缓存值或默认值
        """
        if not self.enable_cache or not self.redis_client:
            return default
        
        try:
            value = self.redis_client.get(key)
            if value is not None:
                return pickle.loads(value)
            return default
            
        except Exception as e:
            logger.error(f"获取缓存失败: {key}, 错误: {e}")
            return default
    
    def set(self, key: str, value: Any, expire: Optional[int] = None) -> bool:
        """
        设置缓存值
        
        Args:
            key: 缓存键
            value: 缓存值
            expire: 过期时间（秒）
            
        Returns:
            是否设置成功
        """
        if not self.enable_cache or not self.redis_client:
            return False
        
        try:
            serialized_value = pickle.dumps(value)
            if expire:
                self.redis_client.setex(key, expire, serialized_value)
            else:
                self.redis_client.set(key, serialized_value)
            return True
            
        except Exception as e:
            logger.error(f"设置缓存失败: {key}, 错误: {e}")
            return False
    
    def delete(self, key: str) -> bool:
        """
        删除缓存
        
        Args:
            key: 缓存键
            
        Returns:
            是否删除成功
        """
        if not self.enable_cache or not self.redis_client:
            return False
        
        try:
            result = self.redis_client.delete(key)
            return result > 0
            
        except Exception as e:
            logger.error(f"删除缓存失败: {key}, 错误: {e}")
            return False
    
    def exists(self, key: str) -> bool:
        """
        检查缓存是否存在
        
        Args:
            key: 缓存键
            
        Returns:
            是否存在
        """
        if not self.enable_cache or not self.redis_client:
            return False
        
        try:
            return self.redis_client.exists(key) > 0
            
        except Exception as e:
            logger.error(f"检查缓存失败: {key}, 错误: {e}")
            return False
    
    def expire(self, key: str, seconds: int) -> bool:
        """
        设置缓存过期时间
        
        Args:
            key: 缓存键
            seconds: 过期时间（秒）
            
        Returns:
            是否设置成功
        """
        if not self.enable_cache or not self.redis_client:
            return False
        
        try:
            return self.redis_client.expire(key, seconds)
            
        except Exception as e:
            logger.error(f"设置过期时间失败: {key}, 错误: {e}")
            return False
    
    def clear_pattern(self, pattern: str) -> int:
        """
        清除匹配模式的缓存
        
        Args:
            pattern: 匹配模式
            
        Returns:
            清除的缓存数量
        """
        if not self.enable_cache or not self.redis_client:
            return 0
        
        try:
            keys = self.redis_client.keys(pattern)
            if keys:
                return self.redis_client.delete(*keys)
            return 0
            
        except Exception as e:
            logger.error(f"清除缓存失败: {pattern}, 错误: {e}")
            return 0
    
    def get_stats(self) -> Dict[str, Any]:
        """
        获取缓存统计信息
        
        Returns:
            统计信息
        """
        if not self.enable_cache or not self.redis_client:
            return {"enabled": False}
        
        try:
            info = self.redis_client.info()
            return {
                "enabled": True,
                "connected_clients": info.get("connected_clients", 0),
                "used_memory_human": info.get("used_memory_human", "0B"),
                "total_commands_processed": info.get("total_commands_processed", 0),
                "keyspace_hits": info.get("keyspace_hits", 0),
                "keyspace_misses": info.get("keyspace_misses", 0)
            }
            
        except Exception as e:
            logger.error(f"获取缓存统计失败: {e}")
            return {"enabled": False, "error": str(e)}

class VectorCache:
    """向量缓存管理器"""
    
    def __init__(self, cache_manager: CacheManager):
        self.cache_manager = cache_manager
        self.prefix = "vector"
        self.default_expire = 3600  # 1小时
    
    def get_embedding(self, text: str) -> Optional[List[float]]:
        """获取文本的向量嵌入"""
        key = self.cache_manager._generate_key(self.prefix, "embedding", hash(text))
        return self.cache_manager.get(key)
    
    def set_embedding(self, text: str, embedding: List[float]) -> bool:
        """设置文本的向量嵌入"""
        key = self.cache_manager._generate_key(self.prefix, "embedding", hash(text))
        return self.cache_manager.set(key, embedding, self.default_expire)
    
    def get_search_results(self, query: str, top_k: int) -> Optional[List[Dict[str, Any]]]:
        """获取搜索结果缓存"""
        key = self.cache_manager._generate_key(self.prefix, "search", hash(query), top_k)
        return self.cache_manager.get(key)
    
    def set_search_results(self, query: str, top_k: int, results: List[Dict[str, Any]]) -> bool:
        """设置搜索结果缓存"""
        key = self.cache_manager._generate_key(self.prefix, "search", hash(query), top_k)
        return self.cache_manager.set(key, results, 1800)  # 30分钟
    
    def clear_embeddings(self):
        """清除所有向量嵌入缓存"""
        pattern = f"{self.prefix}:embedding:*"
        return self.cache_manager.clear_pattern(pattern)
    
    def clear_search_results(self):
        """清除所有搜索结果缓存"""
        pattern = f"{self.prefix}:search:*"
        return self.cache_manager.clear_pattern(pattern)

class FileCache:
    """文件缓存管理器"""
    
    def __init__(self, cache_manager: CacheManager):
        self.cache_manager = cache_manager
        self.prefix = "file"
        self.default_expire = 7200  # 2小时
    
    def get_file_metadata(self, file_id: str) -> Optional[Dict[str, Any]]:
        """获取文件元数据缓存"""
        key = self.cache_manager._generate_key(self.prefix, "metadata", file_id)
        return self.cache_manager.get(key)
    
    def set_file_metadata(self, file_id: str, metadata: Dict[str, Any]) -> bool:
        """设置文件元数据缓存"""
        key = self.cache_manager._generate_key(self.prefix, "metadata", file_id)
        return self.cache_manager.set(key, metadata, self.default_expire)
    
    def get_file_chunks(self, file_id: str) -> Optional[List[Dict[str, Any]]]:
        """获取文件分块缓存"""
        key = self.cache_manager._generate_key(self.prefix, "chunks", file_id)
        return self.cache_manager.get(key)
    
    def set_file_chunks(self, file_id: str, chunks: List[Dict[str, Any]]) -> bool:
        """设置文件分块缓存"""
        key = self.cache_manager._generate_key(self.prefix, "chunks", file_id)
        return self.cache_manager.set(key, chunks, self.default_expire)
    
    def clear_file_cache(self, file_id: str):
        """清除指定文件的缓存"""
        patterns = [
            f"{self.prefix}:metadata:{file_id}",
            f"{self.prefix}:chunks:{file_id}"
        ]
        for pattern in patterns:
            self.cache_manager.clear_pattern(pattern)
    
    def clear_all_file_cache(self):
        """清除所有文件缓存"""
        pattern = f"{self.prefix}:*"
        return self.cache_manager.clear_pattern(pattern)

# 全局缓存管理器实例
cache_manager = CacheManager()
vector_cache = VectorCache(cache_manager)
file_cache = FileCache(cache_manager)
